/*
  Copyright (C) 2011, Kyungjoo Kim
  
  This file is part of UHM (Unassembled HyperMatrix) sparse direct solver. 
  
  All rights reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.
  
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
  
  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  Also add information on how to contact you by electronic and paper mail.
  
  
  Kyungjoo Kim
  iamkyungjoo@gmail.com
*/
#ifndef UHM_UTIL_UTIL_HXX
#define UHM_UTIL_UTIL_HXX

#define UHM_TIME_LEVEL_USER     1
#define UHM_TIME_LEVEL_FRONT    2
#define UHM_TIME_LEVEL_INTERNAL 3

namespace uhm {


  extern Int_ initialize(int argc, char **argv);
  extern Int_ finalize();

  extern void hold();

  extern Double_ stopwatch();
  extern void set_time_ostream(std::ostream &os);

  extern void time_begin(Int_ enabled=UHM_TIME_LEVEL_USER);
  extern void time_end();
  extern Int_ time_stack_size();
  extern void time_flush();

  extern void time_in(const Char_* name, Int_ level=UHM_TIME_LEVEL_USER);
  extern Double_ time_out(Int_ level=UHM_TIME_LEVEL_USER);

  extern void storage_counter_reset();
  extern void storage_counter(Double_ &storage, Double_ &max_storage);
  extern void storage_counter_in(Double_ storage);
  extern void storage_counter_out(Double_ storage);


  // Flop counting
  extern Double_ get_flop_gemm       ( Bool_ is_complex, Int_ m, Int_ n, Int_ k );
  extern Double_ get_flop_syrk       ( Bool_ is_complex, Int_ k, Int_ n );
  extern Double_ get_flop_trsm_lower ( Bool_ is_complex, Int_ m, Int_ n );
  extern Double_ get_flop_trsm_upper ( Bool_ is_complex, Int_ m, Int_ n );
  extern Double_ get_flop_trmm_lower ( Bool_ is_complex, Int_ m, Int_ n );
  extern Double_ get_flop_trmm_upper ( Bool_ is_complex, Int_ m, Int_ n );
  extern Double_ get_flop_lu         ( Bool_ is_complex, Int_ m, Int_ n );
  extern Double_ get_flop_chol       ( Bool_ is_complex, Int_ n );
  extern Double_ get_flop_ldl        ( Bool_ is_complex, Int_ n );
  extern Double_ get_flop_qr         ( Bool_ is_complex, Int_ m, Int_ n );
  extern Double_ get_flop_q          ( Bool_ is_complex, Int_ m, Int_ n, Int_ k );

  extern Double_ get_buffer          ( Int_ datasize, Int_ m, Int_ n );
}

#endif
